package my.wechat.rc.common;


import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Map;

/**
 * Created by hx-pc on 17-5-25.
 */
@SuppressWarnings("all")
public class HttpClientUtil {

    public static <T> T get(String url, Map param, Class<T> responseClass) throws IOException, URISyntaxException {
        URIBuilder uriBuilder = getUriBuild(url);
        return get(uriBuilder, (Map<String, Object>) param, responseClass);
    }

    private static <T> T get(URIBuilder uriBuilder, Map<String, Object> param, Class<T> responseClass) throws IOException, URISyntaxException {
        if (param != null) {
            for (Map.Entry entry : param.entrySet()) {
                if (entry.getKey() != null && entry.getValue() != null) {
                    uriBuilder = uriBuilder.setParameter(entry.getKey().toString(), entry.getValue().toString());
                }
            }
        }
        HttpGet httpGet = new HttpGet(uriBuilder.build());
        return doRequest(responseClass, httpGet);
    }

    public static <T> T post(String url, Map param, Class<T> responseClass) throws IOException, URISyntaxException {
        URIBuilder uriBuilder = getUriBuild(url);
        return post(uriBuilder, (Map<String, Object>) param, responseClass);
    }

    private static <T> T post(URIBuilder uriBuilder, Map<String, Object> param, Class<T> responseClass) throws IOException, URISyntaxException {
        HttpPost httpPost = new HttpPost(uriBuilder.build());
        StringEntity stringEntity;
        if (param != null) {
            stringEntity = new StringEntity(JsonUtil.objToStr(param), Charset.defaultCharset());
        } else {
            stringEntity = new StringEntity("{}", Charset.defaultCharset());
        }
        stringEntity.setContentType("application/json;charset=UTF-8");
        stringEntity.setContentEncoding("UTF-8");
        httpPost.setEntity(stringEntity);
        return doRequest(responseClass, httpPost);
    }

    private static <T> T doRequest(Class<T> responseClass, HttpRequestBase httpRequestBase) throws IOException, URISyntaxException {
        CloseableHttpClient httpclient = getHttpClient();
        buildHeader(httpRequestBase);
        return getResponse(responseClass, httpclient, httpRequestBase);
    }

    private static void buildHeader(HttpRequestBase httpRequestBase) {
        httpRequestBase.addHeader("Content-Type", "application/json;charset=UTF-8");
    }

    private static CloseableHttpClient getHttpClient() {
        RequestConfig defaultRequestConfig = RequestConfig.custom()
                .setConnectTimeout(1000)
                .setSocketTimeout(120 * 1000)
                .build();
        return HttpClientBuilder.create().setDefaultRequestConfig(defaultRequestConfig).build();
    }

    private static <T> T getResponse(Class<T> responseClass, CloseableHttpClient httpclient, HttpRequestBase httpRequestBase) throws IOException {
        CloseableHttpResponse response = httpclient.execute(httpRequestBase);
        HttpEntity entity = response.getEntity();
        String body = EntityUtils.toString(entity, Charset.defaultCharset());
        EntityUtils.consume(entity);
        response.addHeader("Content-Type", "application/json;charset=UTF-8");
        response.close();
        System.out.println(httpRequestBase.toString() + "\n" +
                Arrays.toString(httpRequestBase.getAllHeaders()) + "\n" +
                "-------------------------------------------------------------\n" +
                body +
                "\n-------------------------------------------------------------");
        return JsonUtil.strToObj(body, responseClass);
    }

    public static URIBuilder getUriBuild(String host, Integer port, String path) throws URISyntaxException {
        return new URIBuilder().setScheme("http").setHost(host).setPort(port).setPath(path);
    }

    public static URIBuilder getUriBuild(String url) throws URISyntaxException {
        return new URIBuilder(url);
    }
}
